'' Compresses 'fixed.map' into a series of arrays
'' Using crude RLE

'' First it makes a stream of 240 tiles and 64 attributes,
'' Then it RLE's the stream and puts it into an array.

Sub usage
	Print "$ cmpfixed2 fixed.map pallist.txt screens.h [max]"
	Print
	Print "fixed.map should contain N 16x15 metatiles screens stacked vertically."
	Print "pallist.txt should contain the palette # for each metatile used."
	Print "If max is found, don't compress more than max screens"
End Sub

Dim As Integer i, ns, si, rsi, y, x
Dim As String palString
Dim As uByte pal (255)
Dim As uByte stream (240+64), d, map (15,15)
Dim As uByte rled (1023)
Dim As uByte bytesUsed (255), firstUnused
Dim As Integer fIn, fOut
Dim As Integer runMode, runLength, sizeT, max
Dim As uByte rleByte, runByte

If Command (3) = "" Then usage: End
max = Val (Command (4))

fIn = FreeFile
Open Command (2) For Input As #fIn
Line Input #fIn, palString	
Close #fIn
For i = 1 To Len (palString)
	pal (i - 1) = Val (Mid (palString, i, 1))
Next i

fOut = FreeFile
Open Command (3) For Output As #fOut
Print #fOut, "// " & Command (3) & " generated by cmpfixed2.exe"
Print #fOut, "// Copyleft 2013, 2019 by The Mojon Twins"
Print #fOut, "// Spending time in useless new tools for outdated games!"
Print #fOut, ""

fIn = FreeFile
Open Command (1) For Input As #fIn

ns = 0

Print "cmpfixed2 v0.1 20190705"

While Not Eof (fIn)
	Print "#" & ns;
	Print "~ Reading"; 
	si = 0

	For i = 1 To 240
		Get #fIn, , d
		stream (si) = d
		map (si \ 16, si Mod 16) = d
		si = si + 1
	Next i

	Print " ~ Calc. attrs";
	For y = 0 To 7
		For x = 0 To 7
			d = pal (map (2 * y, 2* x))
			d = d + (pal (map (2 * y, 2 * x + 1)) Shl 2)
			d = d + (pal (map (2 * y + 1, 2 * x)) Shl 4)
			d = d + (pal (map (2 * y + 1, 2 * x + 1)) Shl 6)
			stream (si) = d
			si = si + 1
		next x
	next y

	Print " ~ Find marker"
	For i = 0 To 255: bytesUsed (i) = 0: Next i
	
	For i = 0 To si - 1
		bytesUsed (stream (i)) = -1		
	Next i

	firstUnused = -1
	For i = 0 To 255
		If bytesUsed (i) = 0 Then firstUnused = i: Exit For
	Next i
	If firstUnused = -1 Then Print "All 8bit vals used in stream, can't RLE.": End

	' marker is firstUnused, write to RLE stream
	rled (0) = firstUnused: rsi = 1

	Print " ~ RLEing stream";
	i = 0: rleByte = firstUnused: runMode = 0
	While i < si
		If runMode Then
			runByte = stream (i): i = i + 1
			If runByte = rleByte And runLength < 254 Then
				runLength = runLength + 1
			Else
				If runLength = 1 Then
					rled (rsi - 1) = rleByte
				Else
					rled (rsi) = runLength: rsi = rsi + 1
				End If
				runMode = 0

				rled (rsi) = runByte: rsi = rsi + 1
				rleByte = runByte
			End If
		Else
			runByte = stream (i): i = i + 1
			If runByte <> rleByte Then	
				rled (rsi) = runByte: rsi = rsi + 1
				rleByte = runByte
			Else
				rled (rsi) = firstUnused: rsi = rsi + 1
				runLength = 1
				runMode = -1
			End If
		End If
	Wend
	If runMode Then rled (rsi)= runLength: rsi = rsi + 1

	' End marker
	rled (rsi) = firstUnused: rsi = rsi + 1
	rled (rsi) = 0: rsi = rsi + 1
	Print " " & rsi & " bytes";

	Print " ~ Writing RLE data to rlets_" & ns;

	Print #fOut, "const unsigned char rlets_" & ns & "[] = {"
	For i = 0 To rsi - 1
		If i Mod 16 = 0 Then Print #fOut, "	";
		Print #fOut, "0x" & Hex (rled (i), 2);
		If i < rsi - 1 Then Print #fOut, ", ";
		If i Mod 16 = 15 Or i = rsi - 1 Then Print #fOut, ""
	Next i
	Print #fOut, "};"
	Print #fOut, ""

	ns = ns + 1
	Print

	If max <> 0 And ns = max Then Exit While
Wend

Print "DONE!"

Close
